/** 
 * 卡片类
 */
class Poker {
	/**
	 * @param {Object} param
	 * 构造函数：初始化poker具有4个属性
	 * text:显示的牌文本
	 * number:该牌序号
	 * type:花色，0，1，2，3可以任意指定一个花色，如梅花
	 * selected:是否选中
	 */
	constructor(param) {
		if (param.text) {
			this.text = param.text;
			this.number = Poker.textToNumber(param.text);
		} else {
			this.number = param.number;
			this.text = Poker.numberToText(param.number);
		}
		this.type = param.type;
		this.selected = param.selected;
	}

    /**
	 * @param {Object} text 文本
	 * 文本转序号
	 */
	static textToNumber(text) {
		switch (text) {
			case '3':
				return 3;
			case '4':
				return 4;
			case '5':
				return 5;
			case '6':
				return 6;
			case '7':
				return 7;
			case '8':
				return 8;
			case '9':
				return 9;
			case '10':
			case '0':
			case 'T':
			case 't':
				return 10;
			case '11':
			case 'j':
			case 'J':
				return 11;
			case '12':
			case 'q':
			case 'Q':
				return 12;
			case '13':
			case 'k':
			case 'K':
				return 13;
			case '1':
			case 'a':
			case 'A':
				return 14;
			case '2':
				return 15;
			case 's':
			case 'S':
				return 16;
			case 'x':
			case 'X':
				return 17;
		}
	}

	/**
	 * @param {Object} number序号
	 * 序号转文本
	 * S:小王
	 * X:大王
	 */
	static numberToText(number) {
		switch (number) {
			case 3:
				return '3';
			case 4:
				return '4';
			case 5:
				return '5';
			case 6:
				return '6';
			case 7:
				return '7';
			case 8:
				return '8';
			case 9:
				return '9';
			case 10:
				return '10';
			case 11:
				return 'J';
			case 12:
				return 'Q';
			case 13:
				return 'K';
			case 14:
				return 'A';
			case 15:
				return '2';
			case 16:
				return 'S'; //小王
			case 17:
				return 'X'; //大王
		}
	}

	/** 
	 * 牌排序
	 */
	static sortFunction(a, b) {
		return a.number - b.number;
	}

	/** 
	 * 判断出牌牌型
	 * 符合牌型可以出牌，不符合不能出牌
	 * 对子，三带一，炸弹...
	 * pokerList：一组牌
	 */
	static getObjByPokerList(pokerList) {
		/** 如何是pass 直接返回pass类型 */
		if (pokerList[0] === 'pass') {
			return {
				type: 'pass',
				poker: pokerList,
			};
		}
		/** 排序：通过牌的序号number值排序 */
		pokerList.sort(Poker.sortFunction);

		/** 
		 * 拆牌
		 * 把相同的牌值放入一个数组curList，再全部放入lists，形成一个二维数组
		 * pokerList：原始牌面数组
		 * lists：包含拆分后的二维数组
		 * Count1List：单牌二维数组
		 * ...
		 */
		let lastPoker = pokerList[0];
		let curList = [lastPoker];
		let lists = [];
		for (let i = 1; i < pokerList.length; i++) {
			if (pokerList[i].number !== lastPoker.number) {
				lists.push(curList);
				curList = [pokerList[i]];
			} else {
				curList.push(pokerList[i]);
			}
			lastPoker = pokerList[i];
		}
		lists.push(curList);

		/** 对二维数组lists进行拆分 */
		let Count1List = [];//单牌
		let Count2List = [];//对子
		let Count3List = [];//三张
		let Count4List = [];//四张
		for (let i = 0; i < lists.length; i++) {
			if (lists[i].length === 3) {
				Count3List.push(lists[i]);
			} else if (lists[i].length === 2) {
				Count2List.push(lists[i]);
			} else if (lists[i].length === 1) {
				Count1List.push(lists[i]);
			} else if (lists[i].length === 4) {
				Count4List.push(lists[i]);
			}
		}
		/** 
		 * 牌型判断
		 * pokerList：用户选择要出的牌
		 * 1张情况：单牌one
		 */
		if (pokerList.length === 1) {
			return {
				type: 'one',
				poker: pokerList,
				one: pokerList,
			};
		/** 
		 * 2张情况：
		 * 1），对子two
		 * 2），王炸sx
		 */
		} else if (pokerList.length === 2) {

			if (Count2List.length === 1) {
				return {
					type: 'two',
					poker: pokerList,
					two: pokerList,
				};
			} else if (pokerList[0].number === 16 && pokerList[1].number === 17) {
				return {
					type: 'sx',
					poker: pokerList,
					sx: pokerList,
				};
			}
		/**
		 * 3张情况：
		 * 三张牌three
		 */
		} else if (pokerList.length === 3) {

			if (Count3List.length === 1) {
				return {
					type: 'three',
					poker: pokerList,
					three: pokerList,
				};
			}
		/** 
		 * 4张情况：
		 * 1），三带一threeWithOne
		 * 2），炸弹（四张牌）four
		 */
		} else if (pokerList.length === 4) {

			if (Count3List.length === 1) {
				return {
					type: 'threeWithOne',
					poker: pokerList,
					three: Count3List[0],
					one: Count1List[0],
				};
			} else if (Count4List.length === 1) {
				return {
					type: 'four',
					poker: pokerList,
					four: pokerList,
				};
			}
		/** 
		 * 5张情况：
		 * 三带二threeWithTwo
		 */
		} else if (pokerList.length === 5) {

			if (Count3List.length === 1 && Count2List.length === 1) {
				return {
					type: 'threeWithTwo',
					poker: pokerList,
					three: Count3List[0],
					two: Count2List[0],
				};
			}
		/** 
		 * 6张情况：
		 * 四带二fourWithOne（四张牌＋两手牌，四带二不是炸弹，5555 ＋ 3 ＋ 8）
		 */
		} else if (pokerList.length === 6) {

			if (Count4List.length === 1 && Count1List.length === 2) {
				return {
					type: 'fourWithOne',
					poker: pokerList,
					four: Count4List[0],
				};
			}
        /** 
		 * 8张情况：
		 * 四带二（四张牌＋两手牌，四带二不是炸弹，4444 ＋ 55 ＋ 77）
		 */
		} else if (pokerList.length === 8) {

			if (Count4List.length === 1 && Count2List.length === 2) {
				return {
					type: 'fourWithTwo',
					poker: pokerList,
					four: Count4List[0],
				};
			}

		}
		/** 
		 * 飞机带翅膀：
		 * 三顺＋同数量的单牌（或同数量的对牌）
		 */
		if (Count3List.length >= 2 && Count3List[Count3List.length - 1][0].number <= 14 && Count3List[0][0].number +
			Count3List.length - 1 === Count3List[Count3List.length - 1][0].number) {
			/** threeWithOneList 三顺＋同数量的单牌 */
			if (pokerList.length - 3 * Count3List.length === Count3List.length) {
				return {
					type: 'threeWithOneList',
					poker: pokerList,
					list: Count3List.map(function(item) {
						return {
							three: item,
						};
					}),
				};
			} else {
				/** threeWithTwoList 三顺＋同数量的队牌 */
				if (Count2List.length === Count3List.length) {
					return {
						type: 'threeWithTwoList',
						poker: pokerList,
						list: Count3List.map(function(item) {
							return {
								three: item,
							};
						}),
					};
				}
			}
		}

		/** 
		 * 单顺oneList：五张或更多的连续单牌（如： 45678 或 78910JQK ）。不包括 2 点和双王。
		 */
		if (pokerList.length >= 5 && pokerList[pokerList.length - 1].number <= 14 && Count1List.length === pokerList
			.length && pokerList[0].number + pokerList.length - 1 === pokerList[pokerList.length - 1].number) {
			return {
				type: 'oneList',
				poker: pokerList,
				list: Count1List.map(function(item) {
					return {
						one: item,
					}
				}),
			}
		}

		/** 
		 * 双顺twoList：三对或更多的连续对牌（如： 334455 、7788991010JJ ）。不包括 2 点和双王。
		 */
		if (pokerList.length >= 6 && pokerList[pokerList.length - 1].number <= 14 && pokerList.length % 2 === 0 &&
			Count2List.length === pokerList.length / 2 && pokerList[0].number + pokerList.length / 2 - 1 ===
			pokerList[pokerList.length - 1].number) {
			return {
				type: 'twoList',
				poker: pokerList,
				list: Count2List.map(function(item) {
					return {
						two: item,
					}
				}),
			}
		}

		/** 
		 * 三顺threeList：二个或更多的连续三张牌（如： 333444 、 555666777888 ）。不包括 2 点和双王。
		 */
		if (pokerList.length >= 6 && pokerList[pokerList.length - 1].number <= 14 && pokerList.length % 3 === 0 &&
			Count3List.length === pokerList.length / 3 && pokerList[0].number + pokerList.length / 3 - 1 ===
			pokerList[pokerList.length - 1].number) {
			return {
				type: 'threeList',
				poker: pokerList,
				list: Count3List.map(function(item) {
					return {
						three: item,
					}
				}),
			}
		}

		return false;
	}

	/** 
	 * 牌数组转成字符串
	 */
	static pokerListToString(pokerList) {
		let result = '';
		for (let i = 0; i < pokerList.length; i++) {
			let str = pokerList[i].toString();
			result += str;
		}
		return result;
	}

	toString() {
		return this.text;
	}

}

export default Poker;
